package br.ufrgs.dbproject.idgenerator.dewey;

import java.util.Stack;

import br.ufrgs.dbproject.idgenerator.ID;

@SuppressWarnings("unchecked")
public class DeweyID implements ID {
	
	private final Stack<Integer> id;
	private String idStringfied;

	protected DeweyID(String idStringfied) {
		
		this.idStringfied = idStringfied;
		this.id = new Stack<Integer>();
		
		if (!idStringfied.isEmpty()) {
			for (String c : idStringfied.split("\\.")) {
				this.id.push(Integer.valueOf(c));
			}
		}
	}

	private DeweyID(Stack<Integer> childID) {
		this.id = childID;
	}

	public static DeweyID createEmptyID() {
		return new DeweyID("");
	}
	
	public static DeweyID createRootID() {
		return new DeweyID("1");
	}
	
	public static DeweyID createFromString(String id) {
		return new DeweyID(id);
	}
	
	public DeweyID createFirstChildID() {
		
		Stack<Integer> childID = (Stack<Integer>) id.clone();
		
		childID.push(1);
		
		return new DeweyID(childID);
	}
	
	public DeweyID createNextSibling() {
		
		Stack<Integer> siblingID = (Stack<Integer>) id.clone();
		Integer brotherID = siblingID.pop();
		
		siblingID.push(++brotherID);
		
		return new DeweyID(siblingID);
	}
	
	public int getDeep() {
		return id.size();
	}
	
	@Override
	public boolean equals(Object obj) {
		
		if (obj == null) {
			return false;
		}
		
		if (obj instanceof String) {
			lazyIdStringfy();
			return idStringfied.equals(obj);
		}
		
		if (!(obj instanceof DeweyID)) {
			return false;
		}
		
		DeweyID that = (DeweyID)obj;
		return id.equals(that.id);
	}
	
	@Override
	public String toString() {
		
		lazyIdStringfy();
		return idStringfied;
	}
	
	public void lazyIdStringfy() {
		
		if (idStringfied == null) {
			StringBuilder idBuilder = new StringBuilder();
			for (Integer localID : id) {
				idBuilder.append(localID).append(".");
			}
			idStringfied = idBuilder.deleteCharAt(idBuilder.length() - 1).toString();
		}
	}
	
	public boolean isRoot() {
		return id.size() == 1;
	}
	
	public boolean isEmpty() {
		return id.isEmpty();
	}
}
